package xj.graph2d.shapes.block;

import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;

import xj.graph2d.DrawShape;
import xj.graph2d.DrawShapeBase;
import xj.graph2d.DrawShapeConstants;
import xj.graph2d.LabelListener;
import xj.graph2d.TextShape;
import xj.graph2d.shapes.BoxLabel;
import xj.graph2d.shapes.RoundRectangleShape;

public class SimpleStatementShape 
  extends RoundRectangleShape 
  implements StatementShape, LabelListener { 

  // statement type 

  public static final int SIMPLE_STATEMENT = 0;
  public static final int VARIABLE_DECL    = 1;
  public static final int ASSIGNMENT       = 2;
  public static final int METHOD_CALL      = 3;
  public static final int INPUT            = 4;
  public static final int OUTPUT           = 5;
  public static final int PREDICATE        = 6;
  public static final int COMMENT          = 7;
  public static final int IMPORT           = 8;
  public static final int STATIC_IMPORT    = 9;
  public static final int ENUMERATION      = 10;

  public static final int PARAMETER          = 1000;
  public static final int ATTRIBUTE          = 1001;
  public static final int METHOD_DECL        = 1002;
  public static final int CONSTRUCTOR_DECL   = 1003;
  public static final int STATIC_METHOD_DECL = 1004;
  public static final int CONSTANT           = 1005;
  public static final int STATIC_FIELD       = 1006;
  public static final int ACTION             = 1007;

  public SimpleStatementShape() {
    this(false);
  }

  public SimpleStatementShape(boolean createComp) {
    super(true, createComp);
    setAllowRotation(false);
    setSymetricResize(false);
    setAcceptSubshape(false);
    setFixedHeight(true);
    nodePad = 2;
  }

  public SimpleStatementShape(float x1, float y1, float x2, float y2) { 
    this(x1, y1, x2, y2, false);
  }

  public SimpleStatementShape(float x1, float y1, float x2, float y2, 
			      boolean createComp) { 
    super(x1, y1, x2, y2, true, createComp);
    setAllowRotation(false);
    setSymetricResize(false);
    setAcceptSubshape(false);
    setFixedHeight(true);
    nodePad = 2;
  }

  @Override
  public DrawShape makeInstance() {
    return new SimpleStatementShape(comp != null);
  }

  @Override
  public void copyTo(DrawShapeBase s) 
    throws CloneNotSupportedException {
    super.copyTo(s);
    if (s instanceof SimpleStatementShape) {
      SimpleStatementShape stmt = (SimpleStatementShape) s;
      stmt.statementType = statementType; 
      stmt.minWidth = minWidth;
      stmt.showEditButton = showEditButton;
    }
  }

  @Override
  public void draw(Graphics2D g2) { 
    super.draw(g2);
    
    if (showEditButton) { 

    }
  }

  public Rectangle2D layoutStatement(float top, float left, float width) { 
    Rectangle2D b = getSubshapeBounds();
    float height = MIN_HEIGHT;
    if (b != null) { 
      //height = Math.max(MIN_HEIGHT, (float) b.getHeight() + 8);
      height = Math.max(MIN_HEIGHT, (float) b.getHeight() + 4);
    }
    setEnds(left, top, left + width, top + height);
    positionLabel();
    calculateBounds();
    return bounds; 
  }  

  @Override
  public void doLayout() {
    float x1 = (float) Math.min(p1.getX(), p2.getX());
    float y1 = (float) Math.min(p1.getY(), p2.getY());
    float w = (float) Math.abs(p2.getX() - p1.getX());
    layoutStatement(y1, x1, w);
    super.doLayout();
  }

  @Override
  public boolean isAcceptSubshape(DrawShape subshape) {
    return false;
    //return acceptSubshape && (subshape != null);
  }

  /*
  @Override
  public int isInside(float px, float py) {
    if (isOnMessage(px, py)) {
      return PointOnMessage;
    }
    return super.isInside(px, py);
  }
  */

  @Override
  public boolean isEdgeSensitive() {
    return (parent == null) && resizable;
  }

  @Override
  public boolean isCornorSensitive() {
    return (parent == null) && resizable;
  }

  public String getText() { 
    DrawShape s = findInRole(DrawShapeConstants.ROLE_NODE_LABEL);
    if (s instanceof TextShape) { 
      TextShape tshape = (TextShape) s;
      return tshape.getText();
    } else if (s instanceof BoxLabel) { 
      BoxLabel box = (BoxLabel) s;
      return box.getText();
    }
    return null;
  }

  public void setText(String str) { 
    DrawShape s = findInRole(DrawShapeConstants.ROLE_NODE_LABEL);
    if (s instanceof TextShape) { 
      TextShape tshape = (TextShape) s;
      tshape.setText(str);
    } else if (s instanceof BoxLabel) { 
      BoxLabel box = (BoxLabel) s;
      box.setText(str);
    }
  }

  public boolean getShowEditButton() { 
    return showEditButton;
  }

  public void setShowEditButton(boolean b) { 
    showEditButton = b;
  }

  public int getMinWidth() { 
    return minWidth;
  }

  public void setMinWidth(int w) { 
    minWidth = w;
  }

  public void calculateBounds() {
    calculateBounds(false); // do not include subshapes
  }

  public void setStatementType(int type) { 
    this.statementType = type; 
  }

  public int getStatementType() { 
    return statementType; 
  }

  public void labelChanged(xj.graph2d.Label label) {
    
  }

  @Override
  protected Map<String, Object> getXMLAttributes() {
    Map<String, Object> attrs = super.getXMLAttributes();
    if (attrs == null) {
      attrs = new HashMap<String, Object>();
    }
    attrs.put("statementType", statementType);
    attrs.put("showEdit", showEditButton);
    attrs.put("minWidth", minWidth);
    return attrs;
  }

  @Override
  protected void processXMLAttributes(org.w3c.dom.Element node) {
    if (node != null) {
      super.processXMLAttributes(node);

      String s;

      s = node.getAttribute("statementType");
      try {
	statementType = Integer.parseInt(s);
	setStatementType(statementType);
      } catch (NumberFormatException ex) {}
      s = node.getAttribute("showEdit");
      if (s != null && s.length() > 0) { 
	showEditButton = Boolean.valueOf(s);
      }
      s = node.getAttribute("minWidth");
      if (s != null && s.length() > 0) { 
	try {
	  minWidth = Integer.parseInt(s);
	} catch (NumberFormatException ex) {}
      }
    }
  }

  protected int statementType = SIMPLE_STATEMENT;

  protected boolean showEditButton = false;

  protected int minWidth = 80;

  protected static final int MIN_HEIGHT = 14; 

  ////////////////////////////////////////////
  // Debugging 
  ////////////////////////////////////////////

}



